package com.vimi8.chick.plugins.utils

import android.annotation.SuppressLint
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.Service
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.*
import android.support.v4.content.FileProvider
import android.util.Log
import android.widget.RemoteViews
import com.vimi8.chick.plugins.R
import java.io.File
import java.io.FileOutputStream
import java.io.InputStream
import java.net.HttpURLConnection
import java.net.URL
import java.util.*

class ServiceDownload : Service() {
    private var TAG = this.javaClass.simpleName
    private var progress: Int = 0
    private var mNotificationManager: NotificationManager? = null

    private var downloadUrl: String? = null

    private var mTitle = "正在下载 %s"

    private var mEroTitle = "下载 %s 出错,请重新操作"

    private var saveFileName = ""

    private var binder: DownloadBinder? = null

    private var serviceIsDownloading = false

    private val mContext = this

    private var downLoadThread: Thread? = null

    private var mNotification: Notification? = null

    private val mHandler = @SuppressLint("HandlerLeak")
    object : Handler() {

        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            when (msg.what) {
                0 -> {
                    Log.i(TAG, "downloadApk complete")
                    progress = 100
                    serviceIsDownloading = false
                    stopSelf()// 停掉服务自身
                    // 下载完毕
                    mNotificationManager!!.cancel(NOTIFY_ID)
                    installAPK(mContext, saveFileName)
                }
                2 -> {
                    Log.i(TAG, "downloadApk cancel")
                    // 取消通知
                    mNotificationManager!!.cancel(NOTIFY_ID)
                }
                1 -> {
                    val current = msg.arg1
                    val max = msg.arg2
                    progress = current * 100 / max
                    Log.i(TAG, "downloadApk $progress%")
                    if (current < max) {
                        val contentView = mNotification!!.contentView
                        contentView.setTextViewText(R.id.tv_download_state, "$mTitle($progress%)")
                        contentView.setProgressBar(R.id.pb_download, max, current, false)
                    } else {
                        val contentView = mNotification!!.contentView
                        contentView.setTextViewText(R.id.tv_download_state, mTitle + "下载完成")
                        contentView.setProgressBar(R.id.pb_download, 100, 100, false)
                        mNotification!!.flags = Notification.FLAG_AUTO_CANCEL
                    }
                    mNotificationManager!!.notify(NOTIFY_ID, mNotification)
                }
            }
        }
    }


    override fun onBind(intent: Intent): IBinder? {
        downloadUrl = intent.getStringExtra(BUNDLE_KEY_DOWNLOAD_URL)
        if (downloadUrl == null || downloadUrl!!.trim { it <= ' ' }.isEmpty() || downloadUrl!!.lastIndexOf("/") == -1) {
            return null
        }
        saveFileName = externalCacheDir.toString() + File.separator + "vimiapp.apk"
        mTitle = String.format(mTitle, intent.getStringExtra(BUNDLE_KEY_TITLE))
        mEroTitle = String.format(mEroTitle, intent.getStringExtra(BUNDLE_KEY_TITLE))
        return binder
    }

    override fun onCreate() {
        super.onCreate()
        binder = DownloadBinder()
        mNotificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        stopForeground(true)// 这个不确定是否有作用
    }

    private fun startDownload() {
        progress = 0
        serviceIsDownloading = true
        setUpNotification()
        downLoadThread = Thread(Runnable {
            val apkFile = saveFileName
            val saveFile = File(apkFile)
            try {
                downloadUpdateFile(downloadUrl, saveFile)
            } catch (e: Exception) {
                //e.printStackTrace();
                //Log.reportError(getApplicationContext(), e.getCause());
                val contentview = mNotification!!.contentView
                contentview.setTextViewText(R.id.tv_download_state, mEroTitle)
                mNotification!!.flags = Notification.FLAG_AUTO_CANCEL
                mNotificationManager!!.notify(NOTIFY_ID, mNotification)
                serviceIsDownloading = false
                stopSelf()// 停掉服务自身
            }
        })
        downLoadThread!!.start()
    }

    /**
     * 创建通知
     */
    private fun setUpNotification() {
        val contentView = RemoteViews(packageName, R.layout.download_service)
        contentView.setTextViewText(R.id.tv_download_state, mTitle)

        val builder: Notification.Builder
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val id = "channel_1"
            val channel = NotificationChannel(id, mTitle, NotificationManager.IMPORTANCE_LOW)
            channel.enableLights(true)
            channel.enableVibration(true)
            mNotificationManager!!.createNotificationChannel(channel)
            builder = Notification.Builder(mContext, id)
                .setCategory(Notification.CATEGORY_MESSAGE)
                .setSmallIcon(R.drawable.download_service_ic)
                .setWhen(System.currentTimeMillis())
                .setCustomContentView(contentView)
                .setOngoing(true)
                .setAutoCancel(false)
                .setTicker("准备下载")
        } else {
            builder = Notification.Builder(mContext)
                .setAutoCancel(false)
                .setTicker("准备下载")
                .setSmallIcon(R.drawable.download_service_ic)
                .setWhen(System.currentTimeMillis())
                .setContent(contentView)
                .setOngoing(true)
        }

        mNotification = builder.build()
        // 放置在"正在运行"栏目中
        mNotification!!.flags = Notification.FLAG_ONGOING_EVENT
        mNotificationManager!!.notify(NOTIFY_ID, mNotification)
    }

    @Throws(Exception::class)
    private fun downloadUpdateFile(downloadUrl: String?, saveFile: File): Long {
        var currentSize = 0
        val totalSize: Long = 0
        val updateTotalSize: Int

        var httpConnection: HttpURLConnection? = null
        var ins: InputStream? = null
        var fos: FileOutputStream? = null

        try {
            //downloadUrl="http://58.16.65.208/appupdatedemo1.1.apk";
            //downloadUrl="http://www.oschina.net/uploads/osc-android-app-2.5.5-release.apk";
            //Thread.sleep(10*1000);
            val url = URL(downloadUrl)
            httpConnection = url.openConnection() as HttpURLConnection
            httpConnection.connectTimeout = 10000
            httpConnection.readTimeout = 20000
            updateTotalSize = httpConnection.contentLength
            if (httpConnection.responseCode == 404) {
                throw Exception("fail!")
            }
            ins = httpConnection.inputStream
            fos = FileOutputStream(saveFile, false)
            val buffer = ByteArray(1024)
            var nowTime = Date().time
            var readSize = ins.read(buffer)
            while (readSize > 0) {
                fos.write(buffer, 0, readSize)
                currentSize += readSize
                //每一秒，发送一次
                if (Date().time - nowTime > 1000) {
                    val msg = mHandler.obtainMessage()
                    msg.what = 1
                    msg.arg1 = currentSize
                    msg.arg2 = updateTotalSize
                    mHandler.sendMessage(msg)
                    nowTime = Date().time
                }
                readSize = ins.read(buffer)
            }

            // 下载完成通知安装
            mHandler.sendEmptyMessage(0)

        } finally {
            if (httpConnection != null) {
                httpConnection.disconnect()
            }
            if (ins != null) {
                ins.close()
            }
            if (fos != null) {
                fos.close()
            }
        }
        return totalSize
    }

    inner class DownloadBinder : Binder() {
        var TAG = this.javaClass.simpleName

        val progress: Int
            get() {
                return progress
            }

        fun start() {
            if (downLoadThread == null || !downLoadThread!!.isAlive) {
                // 下载
                startDownload()
            }
        }

        fun serviceIsDownloading(): Boolean {
            //service 本身只有一个，所以尽管serviceIsDownloading不是static但也能到达效果
            return serviceIsDownloading
        }

        fun cancelNotification() {
            mHandler.sendEmptyMessage(2)
        }

    }

    companion object {

        const val BUNDLE_KEY_DOWNLOAD_URL = "download_url"

        const val BUNDLE_KEY_TITLE = "title"

        private const val NOTIFY_ID = 0


        fun installAPK(context: Context, filePath: String) {
            val file = File(filePath)
            if (!file.exists()) {
                return
            }

            val intent = Intent(Intent.ACTION_VIEW)
            // 判断是否是 AndroidN(24) 以及更高的版本
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
                val contentUri = FileProvider.getUriForFile(
                    context,
                    "${context.packageManager.getPackageInfo(context.packageName, 0).packageName}.fileProvider",
                    file
                )
                intent.setDataAndType(contentUri, "application/vnd.android.package-archive")
            } else {
                intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive")
                intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
            }

            context.startActivity(intent)
        }
    }

}
